﻿/*+===================================================================
File:      BossThree.cpp

Summary:   Định nghĩa các phương thức của BossThree.
===================================================================+*/

#include "BossThree.h"
#include "PlayState.h"
#include "Explosion.h"

// Trạng thái của boss.
#define STATUS_APPREARING		0
#define STATUS_APPREARED		1
#define STATUS_OPENING			2
#define STATUS_OPENED			3
#define STATUS_CLOSING			4
#define STATUS_CLOSE			5
#define STATUS_HIDE				6


// Mảng Sprite boss.
int spriteBossThreeID[6] =
{
	ID_SPRITE_BOSS_THREE_APPEARING,
	ID_SPRITE_BOSS_THREE_APPEARED,
	ID_SPRITE_BOSS_THREE_OPENING,
	ID_SPRITE_BOSS_THREE_OPENED,
	ID_SPRITE_BOSS_THREE_CLOSING,
	ID_SPRITE_BOSS_THREE_APPEARED,
};

CBossThree::CBossThree(D3DXVECTOR2 pos, int id, int typeID) : CMoveableObject(pos, id, typeID)
{
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_BOSS_THREE_APPEARING);
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_BOSS_THREE_APPEARED);
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_BOSS_THREE_OPENING);
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_BOSS_THREE_OPENED);
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_BOSS_THREE_CLOSING);
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_BOSS_THREE_CHILD);
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_BOSS_THREE_DOOR);
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_BOSS_THREE_DIE);
	m_nStatus = STATUS_HIDE;
	m_fTimeChange = 1.0f;
	m_pGun = new CGun(ID_BOSS_THREE_BULLET, 10, 1);

	/*for (int i = 0; i < 8; i++)
	{
		int directionX = i % 2 == 0 ? 1 : -1;
		children[i] = new CBossThreeChild(pos, i, ID_BOSS_THREE_CHILD, directionX);
		children[i]->SetIsLive(false);
	}*/

	m_nChildRelease = 0;

	m_nLife = 30;
	m_box.width = 120;
	m_box.width = 128;
}

CBossThree::~CBossThree()
{
	/*for (int i = 0; i < 8; i++)
	{
		if (children[i])
			delete children[i];
	}*/
	if (m_pGun)
		delete m_pGun;
}

void CBossThree::Update(float timeFrame)
{ 
	if (!m_bIsLive)
		return;

	if (m_fTimeChange > 0.0f)
	{
		m_fTimeChange -= timeFrame;
	}
	else
	{
		m_nStatus = (m_nStatus + 1) % 7;

		// Điều chỉnh thời gian chuyển trạng thái.
		switch (m_nStatus)
		{
			case STATUS_APPREARING:
				m_fTimeChange = 0.3f;
				break;
			case STATUS_APPREARED:
				m_fTimeChange = 0.25f;
				break;
			case STATUS_OPENING:
				m_fTimeChange = 0.45f;
				break;
			case STATUS_OPENED:
				m_fTimeChange = 7.8f;
				break;
			case STATUS_CLOSING:
				m_fTimeChange = 0.45f;
				break;
			case STATUS_CLOSE:
				m_fTimeChange = 0.25f;
				break;
			case STATUS_HIDE:
				m_nChildRelease = 0;
				srand(time(NULL));
				m_pos = BOSS3_POS[rand() % 9];
				m_fTimeChange = 3.0f;
				break;	
		}

		// Nếu trạng thái là HIDE thì ko có sprite.
		if (m_nStatus != STATUS_HIDE)
			m_pSprite = m_pResourceManager->GetSprite(spriteBossThreeID[m_nStatus]);
		else
			m_pSprite = NULL;
	}
	
	if (m_nStatus == STATUS_OPENED)
	{
		if (m_fTimeFire > 0.0f)
		{
			m_fTimeFire -= timeFrame;
		}
		else
		{
			m_fTimeFire = 1.0f;
			m_pGun->Fire(D3DXVECTOR2(m_pos.x, m_pos.y + 18.0f));

			// Thả các con của boss 3.
			if (m_nChildRelease < 8)
			{
				int directionX = m_nChildRelease % 2 == 0 ? 1 : -1;
				D3DXVECTOR2 childPos;
				childPos.x = m_pos.x + 40.0f * directionX;
				childPos.y = m_pos.y + 26.0f;

				CBossThreeChild* child = new CBossThreeChild(childPos, m_nChildRelease, ID_BOSS_THREE_CHILD, directionX);
				CPlayState::s_objsOutSideQuadTree.push_back(child);
				m_nChildRelease++;
			}

			//children[m_nCurIndexChild]->SetPos(childPos);
			//children[m_nCurIndexChild]->SetIsLive(true);
			//m_nCurIndexChild = (m_nCurIndexChild + 1) % 8;
		}
	}
	
	/*for (int i = 0; i < 8; i++)
		children[i]->Update(timeFrame);*/

	if (m_pSprite != NULL)
		m_pSprite->Update(timeFrame);

	UpdateBox(timeFrame);
}

void CBossThree::UpdateCollision(vector<CGameObject*> vecGameObjs, float timeFrame)
{
	if (!m_bIsLive)
		return;

	/*for (int i = 0; i < 8; i++)
		children[i]->UpdateCollision(vecGameObjs, timeFrame);*/

	if (m_nStatus == STATUS_HIDE)
		return;

	float timeCollision = timeFrame;
	float normalx = 0.0f, normaly = 0.0f;
	CGameObject* objCollision = NULL;
	
	//Va chạm với đạn của bill
	for (int i = 0; i < CPlayState::s_billBullets.size(); i++)
	{
		float t = CheckCollision(CPlayState::s_billBullets[i], normalx, normaly, timeFrame);
		if (t < timeFrame && t < timeCollision)
		{
			objCollision = CPlayState::s_billBullets[i];
			timeCollision = t;
		}
	}

	// Xử lí va chạm
	if (objCollision != NULL)
	{
		m_v += m_a * timeCollision;
		m_pos += m_v * timeCollision;
		m_v.x = 0.0f;
		m_v.y = 0.0f;
		objCollision->Kill();
		this->Kill();
	}
}

void CBossThree::Draw()
{
	if (!m_bIsLive)
		return;
	D3DXVECTOR2 pos = CViewport::GetInstance()->TransformMatrix(m_pos);

	if (m_pSprite != NULL)
		m_pSprite->Draw(pos);

	/*for (int i = 0; i < 8; i++)
		children[i]->Draw();*/
}

bool CBossThree::Kill()
{
	if (m_nLife > 1)
		m_nLife--;
	else
	{
		m_bIsLive = false;
		D3DXVECTOR2 exPos;
		CExplosion* explosion = new CExplosion(m_pos, 0, ID_BIG_EXPLOSION);
		CPlayState::s_objsOutSideQuadTree.push_back(explosion);
		g_nScore += 1000;
	}

	return true;
}

void CBossThree::UpdateBox(float timeFrame)
{
	if (m_nStatus != STATUS_OPENED)
	{
		this->m_box = { m_pos.x - m_box.width / 2.0f, m_pos.y + m_box.height / 2.0f, 0, 0, 0, 0 };
	}
	else
	{
		m_box.width = m_pSprite->GetWidth();
		m_box.height = m_pSprite->GetHeight();
		m_box.x = m_pos.x - m_box.width / 2.0f;
		m_box.y = m_pos.y + m_box.height / 2.0f;
		m_box.vX = m_v.x;
		m_box.vY = m_v.y;
	}
}

